package cn.thornbird.orgsync.controller;

import cn.thornbird.orgsync.annotation.CurrentUser;
import cn.thornbird.orgsync.entity.TaskDetail;
import cn.thornbird.orgsync.exception.BadRequestException;
import cn.thornbird.orgsync.exception.ForbiddenException;
import cn.thornbird.orgsync.exception.NotFoundException;
import cn.thornbird.orgsync.model.PageList;
import cn.thornbird.orgsync.model.Result;
import cn.thornbird.orgsync.model.UserData;
import cn.thornbird.orgsync.model.combined.TaskObject;
import cn.thornbird.orgsync.service.TaskService;
import cn.thornbird.orgsync.util.JsonUtil;
import cn.thornbird.orgsync.vo.record.TaskRecord;
import cn.thornbird.orgsync.vo.request.TaskDetailQueryRequest;
import cn.thornbird.orgsync.vo.request.TaskQueryRequest;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/api/task")
@Api
@AllArgsConstructor
public class TaskController {

    public static final List<String> ALLOWED_UPDATE_FIELDS = Arrays.asList("title", "active");

    private final TaskService taskService;

    @GetMapping("find/{id}")
    public Result<TaskObject> find(@CurrentUser @ApiIgnore UserData userData, @PathVariable String id)
            throws ForbiddenException, NotFoundException {
        return Result.success(taskService.find(userData, id));
    }

    @GetMapping("details/{taskId}")
    public Result<PageList<TaskDetail>> getTaskDetails(@CurrentUser @ApiIgnore UserData userData,
                                                       @PathVariable String taskId,
                                                       TaskDetailQueryRequest taskDetailQueryRequest,
                                                       Integer pageNumber, Integer pageSize)
            throws ForbiddenException, NotFoundException {
        return Result.success(taskService.getTaskDetails(userData, taskId,
                taskDetailQueryRequest, pageNumber, pageSize));
    }

    @GetMapping("query")
    public Result<PageList<TaskObject>> query(@CurrentUser @ApiIgnore UserData userData,
                                              TaskQueryRequest taskQueryRequest,
                                              Integer pageNumber, Integer pageSize) {
        return Result.success(taskService.query(userData, taskQueryRequest, pageNumber, pageSize));
    }

    @PostMapping("save")
    public Result<TaskObject> save(@CurrentUser @ApiIgnore UserData userData,
                                   @RequestBody @Valid TaskRecord taskRecord)
            throws BadRequestException, NotFoundException, ForbiddenException {
        taskRecord.setUserId(userData.getId());
        return Result.success(taskService.save(userData, taskRecord));
    }

    @PatchMapping("/update/{field}/{id}")
    public Result<TaskObject> update(@CurrentUser @ApiIgnore UserData userData,
                                     @PathVariable String field, @PathVariable String id,
                                     @RequestBody TaskRecord taskRecord)
            throws BadRequestException, NotFoundException, ForbiddenException {
        if (ALLOWED_UPDATE_FIELDS.indexOf(field) < 0) {
            throw new BadRequestException("不允许修改的字段");
        }

        if (field.equals("title")) {
            if (taskRecord.getTitle() == null || taskRecord.getTitle().trim().equals("")) {
                throw new BadRequestException("标题不能为空");
            }
        } else if (field.equals("active")) {
            if (taskRecord.getActive() == null) {
                taskRecord.setActive(false);
            }
        }

        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put(field, JsonUtil.toMap(taskRecord).get(field));
        taskRecord = JsonUtil.parseObject(JsonUtil.toJsonString(map), TaskRecord.class);
        return Result.success(taskService.save(userData, taskRecord));
    }

    @DeleteMapping("delete/{id}")
    public Result<TaskObject> delete(@CurrentUser @ApiIgnore UserData userData, @PathVariable String id)
            throws BadRequestException, NotFoundException, ForbiddenException {
        return Result.success(taskService.delete(userData, id));
    }

}
